use crate::player::Result;
use ffmpeg_next as ffmpeg;
use ffmpeg::{
    codec::Context as CodecContext,
    format::{context::Input, stream::Stream},
    util::frame::{Audio as AudioFrame, Video as VideoFrame},
};
use std::sync::mpsc::{self, Receiver, Sender};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use parking_lot::Mutex;

use tauri::Window;

use super::events::{
    send_playback_status, send_error,
    send_position_changed, send_volume_changed,
};
use super::processor::{VideoProcessor, AudioProcessor};
use super::state::{PlayerState, VideoInfo, AudioInfo, PlaybackStatus};
use crate::config::PlayerConfig;

const SEEK_TOLERANCE: Duration = Duration::from_millis(100);
const BUFFER_SIZE: usize = 32;  // 缓冲区大小

#[derive(Debug, Clone)]
pub enum PlaybackCommand {
    Play,
    Pause,
    Stop,
    Seek(Duration),
    SetVolume(f32),
    SetMuted(bool),
    SetSpeed(f32),
    UpdateConfig(PlayerConfig),
}

pub struct PlaybackThread {
    command_tx: Sender<PlaybackCommand>,
    window: Window,
    state: Arc<Mutex<PlayerState>>,
    #[allow(dead_code)]
    config: PlayerConfig,
    #[allow(dead_code)]
    video_processor: Option<VideoProcessor>,
}

impl PlaybackThread {
    pub fn new(path: String, window: Window, config: PlayerConfig) -> Result<Self> {
        log::info!("Creating new PlaybackThread for path: {}", path);
        
        // 创建通道
        let (tx, rx) = mpsc::channel();
        let state = Arc::new(Mutex::new(PlayerState::new()));
        
        // 创建播放线程
        let thread_state = Arc::clone(&state);
        let window_clone = window.clone();
        let config_clone = config.clone();

        // 在线程中打开输入文件
        let handle = thread::spawn(move || {
            match ffmpeg::format::input(&path) {
                Ok(input_ctx) => {
                    // 在线程内处理 FFmpeg 上下文
                    if let Err(e) = Self::run_playback_loop(
                        input_ctx,
                        rx,
                        window_clone.clone(),
                        thread_state.clone(),
                        config_clone,
                    ) {
                    log::error!("Playback error: {}", e);
                        let mut state = thread_state.lock();
                        state.set_status(PlaybackStatus::Error(e.to_string()));
                        let _ = send_error(&window_clone, -1, e.to_string(), None);
                    }
                }
                Err(e) => {
                    log::error!("Failed to open input file: {}", e);
                    let mut state = thread_state.lock();
                    state.set_status(PlaybackStatus::Error(e.to_string()));
                    let _ = send_error(&window_clone, -1, e.to_string(), None);
                }
            }
        });

        // 存储线程句柄
        state.lock().set_thread_handle(Some(handle));
        
        Ok(Self {
            command_tx: tx,
            window,
            state: Arc::clone(&state),
            config,
            video_processor: None,
        })
    }

    fn setup_media_info(
        input_ctx: &Input,
        state: &Arc<Mutex<PlayerState>>,
        video_stream: Option<&Stream>,
        audio_stream: Option<&Stream>,
    ) -> Result<()> {
        let mut state = state.lock();
        
        // 使用微秒精度处理总时长
        if input_ctx.duration() > 0 {
            let duration = Duration::from_micros(input_ctx.duration() as u64);
            state.set_duration(duration);
            log::debug!("Media duration set to {} microseconds", input_ctx.duration());
        }
        
        // 设置视频信息
        if let Some(stream) = video_stream {
            let codec_context = CodecContext::from_parameters(stream.parameters())?;
            let video_decoder = codec_context.decoder().video()?;
            
            state.set_video_info(VideoInfo {
                width: video_decoder.width() as u32,
                height: video_decoder.height() as u32,
                frame_rate: {
                    let fps = stream.avg_frame_rate();
                    fps.numerator() as f64 / fps.denominator() as f64
                },
                duration: {
                    let tb = stream.time_base();
                    Duration::from_secs_f64(
                        stream.duration() as f64 * f64::from(tb.numerator()) / f64::from(tb.denominator())
                    )
                },
                codec: ffmpeg::codec::decoder::find(stream.parameters().id())
                    .ok_or_else(|| anyhow::anyhow!("Failed to find video decoder"))?
                    .name()
                    .to_string(),
                bit_rate: Some(video_decoder.bit_rate() as u64),
            });
        }
        
        // 设置音频信息
        if let Some(stream) = audio_stream {
            let codec_context = CodecContext::from_parameters(stream.parameters())?;
            let audio_decoder = codec_context.decoder().audio()?;
            
            state.set_audio_info(AudioInfo {
                sample_rate: audio_decoder.rate() as u32,
                channels: audio_decoder.channels() as u32,
                duration: {
                    let tb = stream.time_base();
                    Duration::from_secs_f64(
                        stream.duration() as f64 * f64::from(tb.numerator()) / f64::from(tb.denominator())
                    )
                },
                codec: ffmpeg::codec::decoder::find(stream.parameters().id())
                    .ok_or_else(|| anyhow::anyhow!("Failed to find audio decoder"))?
                    .name()
                    .to_string(),
                bit_rate: Some(audio_decoder.bit_rate() as u64),
            });
        }
        
        Ok(())
    }

    pub fn send_command(&self, command: PlaybackCommand) -> Result<()> {
        log::info!("Attempting to send command: {:?}", &command);
        
        // 检查命令是否有效
        {
            let state = self.state.lock();
            match (&command, &state.status) {
                (PlaybackCommand::Pause, PlaybackStatus::Paused) => {
                    log::info!("Already in Paused state");
                    return Ok(());
                },
                _ => {}
            }
        }
        
        // 发送命令
        match self.command_tx.send(command.clone()) {
            Ok(_) => {
                log::info!("Command sent successfully: {:?}", command);
                Ok(())
            }
            Err(e) => {
                log::error!("Failed to send command {:?}: {}", command, e);
                    Err(anyhow::anyhow!("Failed to send command: {}", e))
            }
        }
    }

    fn create_decoder(stream: &ffmpeg::format::stream::Stream) -> Result<(Option<ffmpeg::decoder::Video>, Option<ffmpeg::decoder::Audio>)> {
        let codec_params = stream.parameters();
        let context = ffmpeg::codec::Context::from_parameters(codec_params)?;
        
        match stream.parameters().medium() {
            ffmpeg::media::Type::Video => {
                let decoder = context.decoder().video()?;
                Ok((Some(decoder), None))
            },
            ffmpeg::media::Type::Audio => {
                let decoder = context.decoder().audio()?;
                Ok((None, Some(decoder)))
            },
            _ => Ok((None, None))
        }
    }

    fn run_playback_loop(
        mut input_ctx: Input,
        rx: Receiver<PlaybackCommand>,
        window: Window,
        state: Arc<Mutex<PlayerState>>,
        config: PlayerConfig,
    ) -> Result<()> {
        log::info!("Starting playback loop");
        
        // 初始化解码器和处理器
        let mut video_decoder = None;
        let mut audio_decoder = None;
        let mut video_processor = None;
        let mut audio_processor = None;

        // 遍历所有流，同时打印信息并设置解码器
        for (index, stream) in input_ctx.streams().enumerate() {
            let params = stream.parameters();
            log::debug!("Stream {}: {:?}", index, params.medium());
            log::debug!("  Codec ID: {:?}", params.id());
            
            let time_base = stream.time_base();
            log::debug!("  Time base: {}/{}", time_base.numerator(), time_base.denominator());
            
            let duration = stream.duration();
            log::debug!("  Duration: {} (time base units)", duration);
            
            let frame_rate = stream.avg_frame_rate();
            log::debug!("  Frame rate: {}/{}", 
                frame_rate.numerator(), 
                frame_rate.denominator()
            );

            match params.medium() {
                ffmpeg::media::Type::Video => {
                    log::debug!("Found video stream at index {}", index);
                    let context = CodecContext::from_parameters(params)
                        .map_err(|e| anyhow::anyhow!("Failed to create codec context for video: {}", e))?;
                    let decoder = context.decoder().video()
                        .map_err(|e| anyhow::anyhow!("Failed to create video decoder: {}", e))?;
                    
                    log::debug!("  Video size: {}x{}", decoder.width(), decoder.height());
                    log::debug!("  Pixel format: {:?}", decoder.format());
                    log::debug!("  Bit rate: {} bps", decoder.bit_rate());

                    video_decoder = Some(decoder);
                    video_processor = Some(VideoProcessor::new_with_config(
                        stream,
                        config.video_buffer_size,
                        config.video_frame_queue_size,
                    ).map_err(|e| anyhow::anyhow!("Failed to create video processor: {}", e))?);
                },
                ffmpeg::media::Type::Audio => {
                    log::debug!("Found audio stream at index {}", index);
                    let context = CodecContext::from_parameters(params)
                        .map_err(|e| anyhow::anyhow!("Failed to create codec context for audio: {}", e))?;
                    let decoder = context.decoder().audio()
                        .map_err(|e| anyhow::anyhow!("Failed to create audio decoder: {}", e))?;
                    
                    let channels = decoder.channels();
                    let rate = decoder.rate();
                    
                    log::debug!("  Sample rate: {} Hz", rate);
                    log::debug!("  Channels: {}", channels);
                    log::debug!("  Sample format: {:?}", decoder.format());
                    log::debug!("  Bit rate: {} bps", decoder.bit_rate());

                    audio_decoder = Some(decoder);
                    audio_processor = Some(AudioProcessor::new_with_config(
                        channels as u32,
                        rate,
                        config.audio_buffer_size,
                        config.audio_frame_queue_size,
                    ).map_err(|e| anyhow::anyhow!("Failed to create audio processor: {}", e))?);
                },
                _ => {}
            }
        }

        // 确保至少找到了视频流
        if video_decoder.is_none() {
            return Err(anyhow::anyhow!("No video stream found in the input file"));
        }

        // 获取音频流的采样率
        let mut audio_sample_rate = 44100; // 默认值
        if let Some(audio_decoder) = &audio_decoder {
            audio_sample_rate = audio_decoder.rate();
        }

        // 设置硬件加速
        if config.hardware_acceleration {
            if let Some(processor) = &mut video_processor {
                processor.enable_hardware_acceleration()
                    .map_err(|e| anyhow::anyhow!("Failed to enable hardware acceleration: {}", e))?;
            }
        }

        // 设置线程数
        if let Some(stream) = input_ctx.stream(1) {
            let mut codec_context = CodecContext::from_parameters(stream.parameters())
                .map_err(|e| anyhow::anyhow!("Failed to create codec context for threading: {}", e))?;
            codec_context.set_threading(ffmpeg::codec::threading::Config {
                kind: ffmpeg::codec::threading::Type::Frame,
                count: config.thread_count,
            });
        }

        // 创建帧缓冲
        let mut video_frame = VideoFrame::empty();
        let mut audio_frame = AudioFrame::empty();

        'playback: loop {
            let current_status = state.lock().status.clone();

            match current_status {
                PlaybackStatus::Playing => {
                    // 首先检查是否有待处理的命令
                    if let Ok(cmd) = rx.try_recv() {
                        Self::handle_command(
                            cmd,
                            &state,
                            &window,
                            &mut video_processor,
                            &mut input_ctx,
                            &config,
                        )?;
                        continue;  // 处理完命令后重新开始循环
                    }

                    // 然后处理一个数据包
                    match input_ctx.packets().next() {
                        Some((stream, packet)) => {
                            match stream.index() {
                                idx if Some(idx) == Some(1) => {
                                    if let Some(decoder) = &mut video_decoder {
                                        decoder.send_packet(&packet)?;
                                        while decoder.receive_frame(&mut video_frame).is_ok() {
                                            // 统一使用微秒精度的时间戳
                        let time_base = stream.time_base();
                                            let pts = video_frame.pts().unwrap_or(0);
                                            let timestamp = Duration::from_micros(
                                                (pts as f64 * 1_000_000.0 * 
                                                f64::from(time_base.numerator()) / 
                                                f64::from(time_base.denominator())) as u64
                                            );

                                            // 处理视频帧
                                            if let Some(processor) = &mut video_processor {
                                                let frame_rate: f64 = stream.avg_frame_rate().into();
                                                processor.process_frame(
                                                    &video_frame,
                                                    timestamp,
                                                    Duration::from_secs_f64(1.0 / frame_rate),
                                                    &window,
                                                )?;
                                            }

                                            // 更新播放位置
                                            state.lock().set_position(timestamp);
                                            send_position_changed(&window, timestamp, state.lock().duration.unwrap_or_default())?;
                                        }
                                    }
                                },
                                idx if Some(idx) == Some(2) => {
                                    if let Some(decoder) = &mut audio_decoder {
                                        decoder.send_packet(&packet)?;
                                        while decoder.receive_frame(&mut audio_frame).is_ok() {
                                            let time_base = stream.time_base();
                                            let pts = audio_frame.pts().unwrap_or(0);
                                            let timestamp = Duration::from_micros(
                                                (pts as f64 * 1_000_000.0 * 
                                                f64::from(time_base.numerator()) / 
                                                f64::from(time_base.denominator())) as u64
                                            );

                                            let samples = audio_frame.samples() as f64;
                                            let sample_rate = audio_sample_rate as f64;
                                            let duration = Duration::from_micros(
                                                (samples * 1_000_000.0 / sample_rate) as u64
                                            );

                                            if let Some(processor) = &mut audio_processor {
                                                processor.process_frame(&audio_frame, timestamp, duration, &window)?;
                                            }
                                        }
                                    }
                                },
                                _ => {}
                            }
                        },
                        None => {
                            // 到达文件末尾
                            log::info!("Reached end of file");
                            state.lock().set_status(PlaybackStatus::Stopped);
                            break 'playback;
                        }
                    }
                },
                PlaybackStatus::Paused => {
                    if let Ok(cmd) = rx.try_recv() {
                        Self::handle_command(
                            cmd,
                            &state,
                            &window,
                            &mut video_processor,
                            &mut input_ctx,
                            &config,
                        )?;
                    }
                    thread::sleep(Duration::from_millis(10));
                },
                PlaybackStatus::Stopped | PlaybackStatus::Error(_) => {
                    break 'playback;
                },
                _ => {
                    thread::sleep(Duration::from_millis(10));
                }
            }
        }

        // 清理资源
        if let Some(processor) = &mut video_processor {
            processor.clear_queue();
        }
        if let Some(processor) = &mut audio_processor {
            processor.clear_queue();
        }

        Ok(())
    }

    // 将命令处理逻辑抽取到单独的方法
    fn handle_command(
        command: PlaybackCommand,
        state: &Arc<Mutex<PlayerState>>,
        window: &Window,
        video_processor: &mut Option<VideoProcessor>,
        input_ctx: &mut Input,
        #[allow(unused_variables)] config: &PlayerConfig,
    ) -> Result<()> {
        match command {
            PlaybackCommand::Play => {
                let mut state = state.lock();
                if !matches!(state.status, PlaybackStatus::Playing) {
                    state.set_status(PlaybackStatus::Playing);
                    send_playback_status(window, PlaybackStatus::Playing)?;
                }
            },
            PlaybackCommand::Pause => {
                let mut state = state.lock();
                if matches!(state.status, PlaybackStatus::Playing) {
                    state.set_status(PlaybackStatus::Paused);
                    send_playback_status(window, PlaybackStatus::Paused)?;
                    if let Some(processor) = video_processor {
                        processor.clear_queue();
                    }
                }
            },
            PlaybackCommand::Stop => {
                let mut state = state.lock();
                state.set_status(PlaybackStatus::Stopped);
                send_playback_status(window, PlaybackStatus::Stopped)?;
                if let Some(processor) = video_processor {
                    processor.clear_queue();
                }
            },
            PlaybackCommand::Seek(position) => {
                let timestamp = position.as_micros() as i64;
                input_ctx.seek(timestamp, 0..1)?;

                // 清理处理器队列
                if let Some(processor) = video_processor {
                    processor.clear_queue();
                }

                // 更新位置并通知前端
                state.lock().set_position(position);
                let duration = state.lock().duration.unwrap_or_default();
                send_position_changed(window, position, duration)?;
            },
            PlaybackCommand::SetVolume(volume) => {
                let mut state = state.lock();
                state.set_volume(volume);
                send_volume_changed(window, volume, state.muted)?;
            },
            PlaybackCommand::SetMuted(muted) => {
                let mut state = state.lock();
                state.set_muted(muted);
                send_volume_changed(window, state.volume, muted)?;
            },
            PlaybackCommand::SetSpeed(speed) => {
                let mut state = state.lock();
                state.set_speed(speed);
                // 可以添加速度变化事件
            },
            PlaybackCommand::UpdateConfig(new_config) => {
                // 更新处理器配置
                if let Some(processor) = video_processor {
                    processor.update_config(
                        new_config.video_buffer_size,
                        new_config.video_frame_queue_size,
                        new_config.hardware_acceleration,
                    )?;
                }
                // ... 其他配置更新逻辑 ...
            },
        }
        Ok(())
    }

    // 添加资源清理方法
    fn cleanup(&mut self) -> Result<()> {
        log::info!("Cleaning up playback resources");
        
        // 发送停止命令
        self.send_command(PlaybackCommand::Stop)?;
        
        // 等待播放线程结束
        let mut state = self.state.lock();
        if let Some(handle) = state.take_thread_handle() {
            log::info!("Waiting for playback thread to finish");
            if let Err(e) = handle.join() {
                log::error!("Error joining playback thread: {:?}", e);
            }
        }
        
        Ok(())
    }

    fn process_frame(
        &mut self,
        frame: &VideoFrame,
        timestamp: Duration,
        duration: Duration,
        window: &Window,
    ) -> Result<()> {
        if let Some(processor) = &mut self.video_processor {
            processor.process_frame(frame, timestamp, duration, window)?;
        }
        Ok(())
    }

    fn load_media(&mut self, path: &str) -> Result<()> {
        log::info!("Loading media from path: {}", path);
        // 现有的加载逻辑...
        log::info!("Media loaded successfully");
        Ok(())
    }

    fn play(&mut self) -> Result<()> {
        log::info!("Play command received");
        // 现有的播放逻辑...
        log::info!("Playback started");
        Ok(())
    }

    fn pause(&mut self) -> Result<()> {
        log::info!("Pause command received");
        // 现有的暂停逻辑...
        log::info!("Playback paused");
        Ok(())
    }
}

// 实现 Drop trait 以确保资源被正确清理
impl Drop for PlaybackThread {
    fn drop(&mut self) {
        log::info!("Cleaning up PlaybackThread");
        if let Err(e) = self.cleanup() {
            log::error!("Error during cleanup: {}", e);
        }
    }
}

